﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace y12fjydbs_1
{
    public partial class MySerialData
    {
        int cSendCount = 0;

        public bool cStop;

        public readonly MySerialPort cSerialPort;

        Thread threadRecv;

        private byte[] DataArr = new byte[1024];
        int DataArrIndex, DataArrLen;
        private byte[] RemainArr = new byte[1024];
        int RemainArrLen;
        private byte[] FindArr = new byte[1024];
        private int FindArrLen;
        private int DataHeadIndex;

        public MySerialData()
        {
            cSerialPort = new MySerialPort();
            threadRecv = new Thread(RecvData);
            threadRecv.Start();
        }

        #region 烟弹播撒
        public void SendCmd_BS(byte yt_yd, byte left_right, byte timers, List<bool> list)
        {
            byte[] TmpCode = new byte[35];
            TmpCode[0] = 0xDB;
            TmpCode[1] = 0xCC;
            TmpCode[2] = yt_yd;
            TmpCode[3] = 35;
            TmpCode[4] = left_right; //0x01:左播撒器, 0x02:右播撒器
            TmpCode[5] = 0x48; // 播撒 指令识别码
            TmpCode[6] = timers;

            int index = 7;
            int m = 0;
            for (int i = 207; i >= 0; i--)
            {
                TmpCode[index] = (byte)(TmpCode[index] << 1);
                if (list[i])
                {
                    TmpCode[index] = (byte)(TmpCode[index] | 0x01);
                }
                m++;
                if (m >= 8)
                {
                    index++;
                    m = 0;
                }

            }
 

            TmpCode[33] = 0x00;
            TmpCode[34] = 0x00; 
            for (int j = 0; j < 33; j++)
            {
                TmpCode[33] += TmpCode[j];
                TmpCode[34] += TmpCode[33];
            }

            Msg.WriteLine(cSendCount++.ToString(), 5);
            Msg.WriteLine($" -> {((yt_yd == 01) ? "焰条" : "焰弹")} 通道:{left_right.ToString()}   发送播撒命令",5);
            cSerialPort.Send(TmpCode);
        }
        #endregion

        #region 烟弹查询
        public void SendCmd_CX(byte yt_yd,byte left_right, byte code)
        {
            byte[] TmpCode = new byte[12];
            TmpCode[0] = 0xDB;
            TmpCode[1] = 0xCC;
            TmpCode[2] = yt_yd;
            TmpCode[3] = 12;
            TmpCode[4] = left_right; //0x01:左播撒器, 0x02:右播撒器
            TmpCode[5] = 0x41; // 查询 指令识别码
            TmpCode[6] = code; //0x01 查询控制器状态 , 0x02挂弹测试 , 0x03 查询烟弹播撒结果 , 0x04:查询挂弹测试结果

            TmpCode[7] = 0x00;
            TmpCode[8] = 0x00;
            TmpCode[9] = 0x00;
            TmpCode[10] = 0x00;
            TmpCode[11] = 0x00;

            for (int j = 0; j < 10; j++)
            {
                TmpCode[10] += TmpCode[j];
                TmpCode[11] += TmpCode[10];
            }

            string str = string.Empty;
            switch(code)
            {
                case 0x01:
                    str = "查询控制器状态";
                    break;
                case 0x02:
                    str = "挂弹测试";
                    break;
                case 0x03:
                    str = "查询烟弹播撒结果";
                    break;
                case 0x04:
                    str = "查询挂弹测试结果";
                    break; 
            }
            Msg.WriteLine(cSendCount++.ToString(),5);
            Msg.WriteLine($" -> {((yt_yd == 01) ? "焰条" : "焰弹")} 通道:{left_right.ToString()}   发送 [{str}] 命令",5);
            cSerialPort.Send(TmpCode);
        }
        #endregion

        #region 终止播撒
        public void SendCmd_TZ(byte yt_yd, byte left_right)
        {
            byte[] TmpCode = new byte[8];
            TmpCode[0] = 0xDB;
            TmpCode[1] = 0xCC;
            TmpCode[2] = yt_yd;
            TmpCode[3] = 8;
            TmpCode[4] = left_right; //0x01:左播撒器, 0x02:右播撒器
            TmpCode[5] = 0x45; // 终止 指令识别码
            TmpCode[6] = 0x00;
            TmpCode[7] = 0x00;

            for (int j = 0; j < 6; j++)
            {
                TmpCode[6] += TmpCode[j];
                TmpCode[7] += TmpCode[6];
            }
            Msg.WriteLine(cSendCount.ToString(), 5);
            Msg.WriteLine($" -> {((yt_yd == 01) ? "焰条" : "焰弹")} 通道:{left_right.ToString()}   发送终止播撒命令", 5);
            cSerialPort.Send(TmpCode);
        }
        #endregion

        #region 复位
        public void SendCmd_FW(byte yt_yd,byte left_right)
        {
            byte[] TmpCode = new byte[12];
            TmpCode[0] = 0xDB;
            TmpCode[1] = 0xCC;
            TmpCode[2] = yt_yd;
            TmpCode[3] = 8;
            TmpCode[4] = left_right; //0x01:左播撒器, 0x02:右播撒器
            TmpCode[5] = 0x47; // 终止 指令识别码
            TmpCode[6] = 0x00;
            TmpCode[7] = 0x00;

            for (int j = 0; j < 6; j++)
            {
                TmpCode[6] += TmpCode[j];
                TmpCode[7] += TmpCode[6];
            }
            Msg.WriteLine(cSendCount++.ToString(), 5);
            Msg.WriteLine($" -> {((yt_yd==01)?"焰条":"焰弹")} 通道:{left_right.ToString()}   发送复位命令",5);
            cSerialPort.Send(TmpCode);
        }
        #endregion

        #region 接受数据处理
        public void RecvData()
        {
            while (true)
            {
                for (int i = 0; i < 10; i++)
                {
                    if (cStop)
                        return;
                    Thread.Sleep(10);
                }

                byte[] arrMsgRec = cSerialPort.TryMessage(200);
                if (arrMsgRec != null)
                {
                    int count = arrMsgRec.Length;
 
                    Array.ConstrainedCopy(arrMsgRec, 0, DataArr, DataArrLen, count);
                    DataArrIndex = 0;
                    DataArrLen = DataArrLen + count;
                    Msg.WriteLine("\n" + BitConverter.ToString(arrMsgRec, 0, count));
                    if (DataArrLen >= 8)
                    {
                        for (int i = DataArrLen; i < 1024; i++)  DataArr[i] = 0x00;
  
                        FindData(); //数据处理
                    } 
                }

            }
        }
        #endregion


        #region 查找数据帧
        private void FindData()
        {
            while (true)
            {
                if (DataArr[DataArrIndex] == 0xDB && DataArr[DataArrIndex + 1] == 0xCC) //找帧头
                {
                    DataHeadIndex = DataArrIndex;

                    int len = DataArr[DataArrIndex + 3];

                    if (len > 0)
                    {
                        if ((DataHeadIndex + len) <= DataArrLen)
                        {
                            FindArrLen = len;
                            FindArr = new byte[FindArrLen];
                            Array.ConstrainedCopy(DataArr, DataHeadIndex, FindArr, 0, FindArrLen);

                            UnPacking(); //拆包 + 数据处理

                            DataArrIndex += len;

                            RemainArrLen = DataArrLen - DataArrIndex;
                            if (RemainArrLen > 0)
                            {
                                Array.ConstrainedCopy(DataArr, DataArrIndex, RemainArr, 0, RemainArrLen);
                                for (int i = 0; i < 1024; i++) DataArr[i] = 0x00;
                                Array.ConstrainedCopy(RemainArr, 0, DataArr, 0, RemainArrLen);
                                DataArrIndex = 0;
                                DataArrLen = RemainArrLen;
                                if (DataArrLen >= 8)
                                    continue;
                                else
                                    return;
                            }
                            else
                            {
                                DataArrLen = 0;
                                for (int i = 0; i < 1024; i++) DataArr[i] = 0x00;
                                return;
                            }
                        }
                        else
                        {
                            return;
                        }
                    }
                    else
                    {
                        return;
                    }

                }
                else
                {
                    //没找到帧头 继续向下找
                    DataArrIndex++;
                    if (DataArrIndex >= DataArrLen)
                    {
                        return;
                    }
                    else
                    {
                        continue;
                    }
                }
            }
        }
        #endregion

        #region 拆包
        private void UnPacking()
        {
            uint a = 0, b = 0;
            for (int i = 0; i < FindArrLen - 2; i++)
            {
                a += FindArr[i];
                b += a;
            }
            a = a & 0xff;
            b = b & 0xff;
            if (a != FindArr[FindArrLen - 2] || b != FindArr[FindArrLen - 1])
            {
                Msg.WriteLine("校验失败!",50,'-');
                return;
            }

            Msg.WriteLine(" <- " + BitConverter.ToString(FindArr),20);


            if (FindArr[2] == CmdByte.YT)//焰条
            {
                switch (FindArr[5])
                {
                    //执行控制器状态返回信息
                    case 0XA2:  
                        MsgYTA2();
                        break;
                    //执行控制器复位返回信息
                    case 0XA7:  
                        MsgYTA7();
                        break;
                    //焰弹挂弹状态返回信息
                    case 0xA1:  
                        MsgYTA1();
                        break;
                    case 0xA6: 
                        MsgYTA1();
                        break;
                    //焰弹播撒返回信息
                    case 0XA8: 
                        MsgYTA8();
                        break;
                    //终止播撒返回信息
                    case 0XA5: 
                        MsgYTA5();
                        break;

                    default:
                        break;
                }
            }
            else if (FindArr[2] == CmdByte.YD)//焰弹
            {
                switch (FindArr[5])
                {
                    //执行控制器状态返回信息
                    case 0XA2:
                        MsgA2();
                        break;
                    //执行控制器复位返回信息
                    case 0XA7:
                        MsgA7();
                        break;
                    //焰弹挂弹状态返回信息
                    case 0xA1:
                    case 0xA6:
                        MsgA1();
                        break;
                    //焰弹播撒返回信息
                    case 0XA8:
                        MsgA8();
                        break;
                    //终止播撒返回信息
                    case 0XA5:
                        MsgA5();
                        break;

                    default:
                        break;
                }
            }
        }
        #endregion

        #region 焰弹挂弹状态返回信息
        private void MsgA1()
        {
            string msg;
            if(FindArr[5] == 0xA1)
            {
                msg = "挂弹状态返回信息:";
            }
            else
            {
                msg = "查询挂弹测试结果返回信息:";
            } 

            List<bool> list = new List<bool>();
            for (int i = 25; i >=0 ; i--)
            {
                byte b = FindArr[i + 6];
                list.Add((b & 0x01) != 0);
                list.Add((b & 0x02) != 0);
                list.Add((b & 0x04) != 0);
                list.Add((b & 0x08) != 0);
                list.Add((b & 0x10) != 0);
                list.Add((b & 0x20) != 0);
                list.Add((b & 0x40) != 0);
                list.Add((b & 0x80) != 0);
            }

            if (FindArr[4] == 0x01)
            {
                if (MyGlobal.frmYDL != null)
                {
                    msg = "左播撒器 <-- " + msg ;
                    MyGlobal.frmYDL.RecviveMsg(msg,Color.Navy);
                    MyGlobal.frmYDL.RecviveMsgA1(list);
                }
            }
            else if (FindArr[4] == 0x02)
            {
                if(MyGlobal.frmYDR != null)
                {
                    msg = "右播撒器 <-- " + msg;
                    MyGlobal.frmYDR.RecviveMsg(msg, Color.Navy);
                    MyGlobal.frmYDR.RecviveMsgA1(list);
                }
            }
        }
        #endregion

        #region 焰弹播撒状态返回信息
        private void MsgA8()
        {
            string msg = "播撒状态返回信息:";

            Color color = Color.Navy;
            if (FindArr[6] == 0xff)
            {
                color = Color.Navy;
                msg += "已响应命令";
            }
            else if (FindArr[6] == 0x0f)
            {
                color = Color.Navy;
                msg += "播撒已完成";
            }
            else if (FindArr[6] == 0x07)
            {
                color = Color.Red;
                msg += "使能错信号错误,BS弹序号位无意义";
            } 

            List<bool> list = new List<bool>();
            for (int i = 26; i > 0; i--)
            {
                byte b = FindArr[i + 6];
                list.Add((b & 0x01) != 0);
                list.Add((b & 0x02) != 0);
                list.Add((b & 0x04) != 0);
                list.Add((b & 0x08) != 0);
                list.Add((b & 0x10) != 0);
                list.Add((b & 0x20) != 0);
                list.Add((b & 0x40) != 0);
                list.Add((b & 0x80) != 0);
            }

            if (FindArr[4] == 0x01)
            {
                if (MyGlobal.frmYDL != null)
                {
                    msg = "左播撒器 <-- " + msg;
                    MyGlobal.frmYDL.RecviveMsg(msg,color);
                    MyGlobal.frmYDL.RecviveMsgA8(FindArr[6],list);
                }
            }
            else if (FindArr[4] == 0x02)
            {
                if (MyGlobal.frmYDR != null)
                {
                    msg = "右播撒器 <-- " + msg;
                    MyGlobal.frmYDR.RecviveMsg(msg, Color.Navy);
                    MyGlobal.frmYDR.RecviveMsgA8(FindArr[6], list);
                }
            }
        }
        #endregion

        #region 执行控制器状态返回信息
        private void MsgA2()
        {
            string msg = "焰弹执行控制器状态返回信息:";
            string version = "";
            version = ((FindArr[7] & 0xf0) >> 4).ToString() + ".";
            version += ((FindArr[7] & 0x0f)).ToString();
            version += ((FindArr[8] & 0xf0) >> 4).ToString();
            if ((FindArr[8] & 0x0f) != 0x00)
                version += ((char)((FindArr[8] & 0x0f) + 0x40)).ToString().ToLower();
            if (FindArr[4] == 0x01)
            {
                if (MyGlobal.frmYDL != null)
                {
                    msg = "左播撒器 <-- " + msg;
                    msg += $"控制器状态{((FindArr[6] == 0x11) ? "准备好" : "未准备好")}  , 版本:{version}"; 
                    MyGlobal.frmYDL.RecviveMsg(msg,Color.Navy);
                    MyGlobal.frmYDL.RecviveMsgA2(FindArr[6] == 0x11);
                }
            }
            else if (FindArr[4] == 0x02)
            {
                if (MyGlobal.frmYDR != null)
                {
                    msg = "右播撒器 <-- " + msg;
                    msg += $"控制器状态{((FindArr[6] == 0x11) ? "准备好" : "未准备好")}  , 版本:{version}";
                    MyGlobal.frmYDR.RecviveMsg(msg, Color.Navy);
                    MyGlobal.frmYDR.RecviveMsgA2(FindArr[6] == 0x11);
                }
            }
        }
        #endregion

        #region 焰弹终止播撒返回信息
        private void MsgA5()
        {
            string msg = "执行控制器中止焰弹播撒返回信息:成功";
            if (FindArr[4] == 0x01)
            {
                if (MyGlobal.frmYDL != null)
                {
                    msg = "左播撒器 <-- " + msg;
                    MyGlobal.frmYDL.RecviveMsg(msg,Color.Navy);
                    MyGlobal.frmYDL.RecviveMsgA5();
                }
            }
            else if (FindArr[4] == 0x02)
            {
                if (MyGlobal.frmYDR != null)
                {
                    msg = "右播撒器 <-- " + msg;
                    MyGlobal.frmYDR.RecviveMsg(msg, Color.Navy);
                    MyGlobal.frmYDR.RecviveMsgA5();
                }

            }
        }
        #endregion

        #region 执行控制器复位返回信息
        private void MsgA7()
        {
            string msg = "执行控制器复位返回信息:成功";
            if (FindArr[4] == 0x01)
            {
                if (MyGlobal.frmYDL != null)
                {
                    msg = "左播撒器 <-- " + msg;
                    MyGlobal.frmYDL.RecviveMsg(msg, Color.Navy);
                    MyGlobal.frmYDL.RecviveMsgA7();
                }
            }
            else if (FindArr[4] == 0x02)
            {
                if (MyGlobal.frmYDR != null)
                {
                    msg = "右播撒器 <-- " + msg;
                    MyGlobal.frmYDR.RecviveMsg(msg, Color.Navy);
                    MyGlobal.frmYDR.RecviveMsgA7();
                }
            }
        }
        #endregion

    }
}
